package com.my.jfinal;

import java.util.List;
import java.util.Set;

import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.config.JFinalConfig;
import com.jfinal.config.Plugins;
import com.jfinal.config.Routes;
import com.jfinal.core.Controller;
import com.jfinal.core.JFinal;
import com.jfinal.kit.PathKit;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.StrKit;
import com.jfinal.log.Log;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.IDataSourceProvider;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.render.ViewType;
import com.jfinal.template.Engine;
import com.my.core.annotation.shiro.RouterMapping;
import com.my.core.annotation.shiro.TableMapping;
import com.my.core.scan.ClassScan;
import com.my.core.utils.StringUtils;
import com.my.jfinal.plugin.shiro.ShiroInterceptor;
import com.my.jfinal.plugin.shiro.ShiroPlugin;
import com.my.jfinal.util.ClassUtils;
import com.jfinal.ext.handler.ContextPathHandler;

public class SystemConfig extends JFinalConfig {
	static Log log = Log.getLog(SystemConfig.class);
	private Routes routes;
	@Override
	public void configConstant(Constants me) {
		// TODO Auto-generated method stub
		log.info("MyWeb is starting ...");
		PropKit.use("common.properties");
		me.setI18nDefaultBaseName("language");
		me.setDevMode(PropKit.getBoolean("dev_mode"));
		me.setError404View("/error/404.html");
		me.setError500View("/error/500.html");
		me.setViewType(ViewType.JSP);
	}

	@Override
	public void configRoute(Routes me) {
		commonConfigRoute(me);
		this.routes = me;
	}

	private void commonConfigRoute(Routes routes) {
//		List<Class<Controller>> controllerClassList = ClassUtils.scanSubClass(Controller.class);
		Set<Class<Controller>> controllerClassList = ClassScan.findFileClass("com.my.web", Controller.class);
		if (controllerClassList != null) {
			for (Class<?> clazz : controllerClassList) {
				RouterMapping urlMapping = clazz.getAnnotation(RouterMapping.class);
				if (null != urlMapping && StringUtils.isNotBlank(urlMapping.url())) {
					if (StrKit.notBlank(urlMapping.viewPath())) {
						routes.add(urlMapping.url(), (Class<? extends Controller>) clazz, urlMapping.viewPath());
					} else {
						routes.add(urlMapping.url(), (Class<? extends Controller>) clazz);
					}
					log.info(urlMapping.url());
				}
			}
		}
	}

	@Override
	public void configEngine(Engine me) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void configPlugin(Plugins me) {
		// TODO Auto-generated method stub
		DruidPlugin druidPlugin = createDruidPlugin();
		me.add(druidPlugin);
		me.add(createRecordPlugin(druidPlugin));
		ShiroPlugin shiro = new ShiroPlugin(this.routes);
		shiro.setLoginUrl(PropKit.get("loginUrl"));
		shiro.setSuccessUrl(PropKit.get("successUrl"));
		shiro.setUnauthorizedUrl(PropKit.get("loginUrl"));
		me.add(shiro);
	}

	@Override
	public void configInterceptor(Interceptors me) {
		me.add(new ShiroInterceptor());
	}

	@Override
	public void configHandler(Handlers me) {
		me.add(new ContextPathHandler("ctx"));
	}
	
	public DruidPlugin createDruidPlugin() {

		String url = PropKit.get("db_url").trim();
		String db_user = PropKit.get("db_user").trim();
		String db_password = PropKit.get("db_password").trim();
		String driverClass = PropKit.get("driver_class");
		driverClass = StringUtils.isNotBlank(driverClass) ? driverClass.trim() : "com.mysql.jdbc.Driver";
		return new DruidPlugin(url, db_user, db_password,driverClass);
	}
	
	public ActiveRecordPlugin createRecordPlugin(IDataSourceProvider dsp) {
		ActiveRecordPlugin arPlugin = new ActiveRecordPlugin(dsp);
//		List<Class<Model>> modelClassList = ClassUtils.scanSubClass(Model.class);
		Set<Class<Model>> modelClassList = ClassScan.findFileClass("com.my.dao", Model.class);
		if (modelClassList != null) {
			for (Class<?> clazz : modelClassList) {
				TableMapping tb = clazz.getAnnotation(TableMapping.class);
				if (tb == null)
					continue;
				String tname = tb.tableName();
				if (StringUtils.isNotBlank(tb.primaryKey())) {
					arPlugin.addMapping(tname, tb.primaryKey(), (Class<? extends Model<?>>) clazz);
				} else {
					arPlugin.addMapping(tname, (Class<? extends Model<?>>) clazz);
				}
			}
		}
		arPlugin.setBaseSqlTemplatePath(PathKit.getRootClassPath());
//		MappingKit.
		arPlugin.setShowSql(JFinal.me().getConstants().getDevMode());
		return arPlugin;
	}

}
